// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Code generated by sidekick. DO NOT EDIT.

#![allow(rustdoc::redundant_explicit_links)]
#![allow(rustdoc::broken_intra_doc_links)]
#![no_implicit_prelude]
extern crate async_trait;
extern crate bytes;
extern crate gax;
extern crate gaxi;
extern crate gtype;
extern crate iam_v1;
extern crate iam_v2;
extern crate lazy_static;
extern crate reqwest;
extern crate rpc;
extern crate serde;
extern crate serde_json;
extern crate serde_with;
extern crate std;
extern crate tracing;
extern crate wkt;

mod debug;
mod deserialize;
mod serialize;

/// Request for
/// [TroubleshootIamPolicy][google.cloud.policytroubleshooter.iam.v3.PolicyTroubleshooter.TroubleshootIamPolicy].
///
/// [google.cloud.policytroubleshooter.iam.v3.PolicyTroubleshooter.TroubleshootIamPolicy]: crate::client::PolicyTroubleshooter::troubleshoot_iam_policy
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct TroubleshootIamPolicyRequest {
    /// The information to use for checking whether a principal has a permission
    /// for a resource.
    pub access_tuple: std::option::Option<crate::model::AccessTuple>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl TroubleshootIamPolicyRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [access_tuple][crate::model::TroubleshootIamPolicyRequest::access_tuple].
    pub fn set_access_tuple<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::AccessTuple>,
    {
        self.access_tuple = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [access_tuple][crate::model::TroubleshootIamPolicyRequest::access_tuple].
    pub fn set_or_clear_access_tuple<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::AccessTuple>,
    {
        self.access_tuple = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for TroubleshootIamPolicyRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.policytroubleshooter.iam.v3.TroubleshootIamPolicyRequest"
    }
}

/// Response for
/// [TroubleshootIamPolicy][google.cloud.policytroubleshooter.iam.v3.PolicyTroubleshooter.TroubleshootIamPolicy].
///
/// [google.cloud.policytroubleshooter.iam.v3.PolicyTroubleshooter.TroubleshootIamPolicy]: crate::client::PolicyTroubleshooter::troubleshoot_iam_policy
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct TroubleshootIamPolicyResponse {
    /// Indicates whether the principal has the specified permission for the
    /// specified resource, based on evaluating all types of the applicable IAM
    /// policies.
    pub overall_access_state: crate::model::troubleshoot_iam_policy_response::OverallAccessState,

    /// The access tuple from the request, including any provided context used to
    /// evaluate the condition.
    pub access_tuple: std::option::Option<crate::model::AccessTuple>,

    /// An explanation of how the applicable IAM allow policies affect the final
    /// access state.
    pub allow_policy_explanation: std::option::Option<crate::model::AllowPolicyExplanation>,

    /// An explanation of how the applicable IAM deny policies affect the final
    /// access state.
    pub deny_policy_explanation: std::option::Option<crate::model::DenyPolicyExplanation>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl TroubleshootIamPolicyResponse {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [overall_access_state][crate::model::TroubleshootIamPolicyResponse::overall_access_state].
    pub fn set_overall_access_state<
        T: std::convert::Into<crate::model::troubleshoot_iam_policy_response::OverallAccessState>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.overall_access_state = v.into();
        self
    }

    /// Sets the value of [access_tuple][crate::model::TroubleshootIamPolicyResponse::access_tuple].
    pub fn set_access_tuple<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::AccessTuple>,
    {
        self.access_tuple = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [access_tuple][crate::model::TroubleshootIamPolicyResponse::access_tuple].
    pub fn set_or_clear_access_tuple<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::AccessTuple>,
    {
        self.access_tuple = v.map(|x| x.into());
        self
    }

    /// Sets the value of [allow_policy_explanation][crate::model::TroubleshootIamPolicyResponse::allow_policy_explanation].
    pub fn set_allow_policy_explanation<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::AllowPolicyExplanation>,
    {
        self.allow_policy_explanation = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [allow_policy_explanation][crate::model::TroubleshootIamPolicyResponse::allow_policy_explanation].
    pub fn set_or_clear_allow_policy_explanation<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::AllowPolicyExplanation>,
    {
        self.allow_policy_explanation = v.map(|x| x.into());
        self
    }

    /// Sets the value of [deny_policy_explanation][crate::model::TroubleshootIamPolicyResponse::deny_policy_explanation].
    pub fn set_deny_policy_explanation<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::DenyPolicyExplanation>,
    {
        self.deny_policy_explanation = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [deny_policy_explanation][crate::model::TroubleshootIamPolicyResponse::deny_policy_explanation].
    pub fn set_or_clear_deny_policy_explanation<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::DenyPolicyExplanation>,
    {
        self.deny_policy_explanation = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for TroubleshootIamPolicyResponse {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.policytroubleshooter.iam.v3.TroubleshootIamPolicyResponse"
    }
}

/// Defines additional types related to [TroubleshootIamPolicyResponse].
pub mod troubleshoot_iam_policy_response {
    #[allow(unused_imports)]
    use super::*;

    /// Whether the principal has the permission on the resource.
    ///
    /// # Working with unknown values
    ///
    /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
    /// additional enum variants at any time. Adding new variants is not considered
    /// a breaking change. Applications should write their code in anticipation of:
    ///
    /// - New values appearing in future releases of the client library, **and**
    /// - New values received dynamically, without application changes.
    ///
    /// Please consult the [Working with enums] section in the user guide for some
    /// guidelines.
    ///
    /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum OverallAccessState {
        /// Not specified.
        Unspecified,
        /// The principal has the permission.
        CanAccess,
        /// The principal doesn't have the permission.
        CannotAccess,
        /// The principal might have the permission, but the sender can't access all
        /// of the information needed to fully evaluate the principal's access.
        UnknownInfo,
        /// The principal might have the permission, but Policy Troubleshooter can't
        /// fully evaluate the principal's access because the sender didn't provide
        /// the required context to evaluate the condition.
        UnknownConditional,
        /// If set, the enum was initialized with an unknown value.
        ///
        /// Applications can examine the value using [OverallAccessState::value] or
        /// [OverallAccessState::name].
        UnknownValue(overall_access_state::UnknownValue),
    }

    #[doc(hidden)]
    pub mod overall_access_state {
        #[allow(unused_imports)]
        use super::*;
        #[derive(Clone, Debug, PartialEq)]
        pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
    }

    impl OverallAccessState {
        /// Gets the enum value.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the string representation of enums.
        pub fn value(&self) -> std::option::Option<i32> {
            match self {
                Self::Unspecified => std::option::Option::Some(0),
                Self::CanAccess => std::option::Option::Some(1),
                Self::CannotAccess => std::option::Option::Some(2),
                Self::UnknownInfo => std::option::Option::Some(3),
                Self::UnknownConditional => std::option::Option::Some(4),
                Self::UnknownValue(u) => u.0.value(),
            }
        }

        /// Gets the enum value as a string.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the integer representation of enums.
        pub fn name(&self) -> std::option::Option<&str> {
            match self {
                Self::Unspecified => std::option::Option::Some("OVERALL_ACCESS_STATE_UNSPECIFIED"),
                Self::CanAccess => std::option::Option::Some("CAN_ACCESS"),
                Self::CannotAccess => std::option::Option::Some("CANNOT_ACCESS"),
                Self::UnknownInfo => std::option::Option::Some("UNKNOWN_INFO"),
                Self::UnknownConditional => std::option::Option::Some("UNKNOWN_CONDITIONAL"),
                Self::UnknownValue(u) => u.0.name(),
            }
        }
    }

    impl std::default::Default for OverallAccessState {
        fn default() -> Self {
            use std::convert::From;
            Self::from(0)
        }
    }

    impl std::fmt::Display for OverallAccessState {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
            wkt::internal::display_enum(f, self.name(), self.value())
        }
    }

    impl std::convert::From<i32> for OverallAccessState {
        fn from(value: i32) -> Self {
            match value {
                0 => Self::Unspecified,
                1 => Self::CanAccess,
                2 => Self::CannotAccess,
                3 => Self::UnknownInfo,
                4 => Self::UnknownConditional,
                _ => Self::UnknownValue(overall_access_state::UnknownValue(
                    wkt::internal::UnknownEnumValue::Integer(value),
                )),
            }
        }
    }

    impl std::convert::From<&str> for OverallAccessState {
        fn from(value: &str) -> Self {
            use std::string::ToString;
            match value {
                "OVERALL_ACCESS_STATE_UNSPECIFIED" => Self::Unspecified,
                "CAN_ACCESS" => Self::CanAccess,
                "CANNOT_ACCESS" => Self::CannotAccess,
                "UNKNOWN_INFO" => Self::UnknownInfo,
                "UNKNOWN_CONDITIONAL" => Self::UnknownConditional,
                _ => Self::UnknownValue(overall_access_state::UnknownValue(
                    wkt::internal::UnknownEnumValue::String(value.to_string()),
                )),
            }
        }
    }

    impl serde::ser::Serialize for OverallAccessState {
        fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
        where
            S: serde::Serializer,
        {
            match self {
                Self::Unspecified => serializer.serialize_i32(0),
                Self::CanAccess => serializer.serialize_i32(1),
                Self::CannotAccess => serializer.serialize_i32(2),
                Self::UnknownInfo => serializer.serialize_i32(3),
                Self::UnknownConditional => serializer.serialize_i32(4),
                Self::UnknownValue(u) => u.0.serialize(serializer),
            }
        }
    }

    impl<'de> serde::de::Deserialize<'de> for OverallAccessState {
        fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
        where
            D: serde::Deserializer<'de>,
        {
            deserializer.deserialize_any(wkt::internal::EnumVisitor::<OverallAccessState>::new(
                ".google.cloud.policytroubleshooter.iam.v3.TroubleshootIamPolicyResponse.OverallAccessState"))
        }
    }
}

/// Information about the principal, resource, and permission to check.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct AccessTuple {
    /// Required. The email address of the principal whose access you want to
    /// check. For example, `alice@example.com` or
    /// `my-service-account@my-project.iam.gserviceaccount.com`.
    ///
    /// The principal must be a Google Account or a service account. Other types of
    /// principals are not supported.
    pub principal: std::string::String,

    /// Required. The full resource name that identifies the resource. For example,
    /// `//compute.googleapis.com/projects/my-project/zones/us-central1-a/instances/my-instance`.
    ///
    /// For examples of full resource names for Google Cloud services, see
    /// <https://cloud.google.com/iam/help/troubleshooter/full-resource-names>.
    pub full_resource_name: std::string::String,

    /// Required. The IAM permission to check for, either in the `v1` permission
    /// format or the `v2` permission format.
    ///
    /// For a complete list of IAM permissions in the `v1` format, see
    /// <https://cloud.google.com/iam/help/permissions/reference>.
    ///
    /// For a list of IAM permissions in the `v2` format, see
    /// <https://cloud.google.com/iam/help/deny/supported-permissions>.
    ///
    /// For a complete list of predefined IAM roles and the permissions in each
    /// role, see <https://cloud.google.com/iam/help/roles/reference>.
    pub permission: std::string::String,

    /// Output only. The permission that Policy Troubleshooter checked for, in
    /// the `v2` format.
    pub permission_fqdn: std::string::String,

    /// Optional. Additional context for the request, such as the request time or
    /// IP address. This context allows Policy Troubleshooter to troubleshoot
    /// conditional role bindings and deny rules.
    pub condition_context: std::option::Option<crate::model::ConditionContext>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl AccessTuple {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [principal][crate::model::AccessTuple::principal].
    pub fn set_principal<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.principal = v.into();
        self
    }

    /// Sets the value of [full_resource_name][crate::model::AccessTuple::full_resource_name].
    pub fn set_full_resource_name<T: std::convert::Into<std::string::String>>(
        mut self,
        v: T,
    ) -> Self {
        self.full_resource_name = v.into();
        self
    }

    /// Sets the value of [permission][crate::model::AccessTuple::permission].
    pub fn set_permission<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.permission = v.into();
        self
    }

    /// Sets the value of [permission_fqdn][crate::model::AccessTuple::permission_fqdn].
    pub fn set_permission_fqdn<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.permission_fqdn = v.into();
        self
    }

    /// Sets the value of [condition_context][crate::model::AccessTuple::condition_context].
    pub fn set_condition_context<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::ConditionContext>,
    {
        self.condition_context = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [condition_context][crate::model::AccessTuple::condition_context].
    pub fn set_or_clear_condition_context<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::ConditionContext>,
    {
        self.condition_context = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for AccessTuple {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.policytroubleshooter.iam.v3.AccessTuple"
    }
}

/// Additional context for troubleshooting conditional role bindings and deny
/// rules.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ConditionContext {
    /// Represents a target resource that is involved with a network activity.
    /// If multiple resources are involved with an activity, this must be the
    /// primary one.
    pub resource: std::option::Option<crate::model::condition_context::Resource>,

    /// The destination of a network activity, such as accepting a TCP connection.
    /// In a multi-hop network activity, the destination represents the receiver of
    /// the last hop.
    pub destination: std::option::Option<crate::model::condition_context::Peer>,

    /// Represents a network request, such as an HTTP request.
    pub request: std::option::Option<crate::model::condition_context::Request>,

    /// Output only. The effective tags on the resource. The effective tags are
    /// fetched during troubleshooting.
    pub effective_tags: std::vec::Vec<crate::model::condition_context::EffectiveTag>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ConditionContext {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [resource][crate::model::ConditionContext::resource].
    pub fn set_resource<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::condition_context::Resource>,
    {
        self.resource = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [resource][crate::model::ConditionContext::resource].
    pub fn set_or_clear_resource<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::condition_context::Resource>,
    {
        self.resource = v.map(|x| x.into());
        self
    }

    /// Sets the value of [destination][crate::model::ConditionContext::destination].
    pub fn set_destination<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::condition_context::Peer>,
    {
        self.destination = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [destination][crate::model::ConditionContext::destination].
    pub fn set_or_clear_destination<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::condition_context::Peer>,
    {
        self.destination = v.map(|x| x.into());
        self
    }

    /// Sets the value of [request][crate::model::ConditionContext::request].
    pub fn set_request<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::condition_context::Request>,
    {
        self.request = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [request][crate::model::ConditionContext::request].
    pub fn set_or_clear_request<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::condition_context::Request>,
    {
        self.request = v.map(|x| x.into());
        self
    }

    /// Sets the value of [effective_tags][crate::model::ConditionContext::effective_tags].
    pub fn set_effective_tags<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::condition_context::EffectiveTag>,
    {
        use std::iter::Iterator;
        self.effective_tags = v.into_iter().map(|i| i.into()).collect();
        self
    }
}

impl wkt::message::Message for ConditionContext {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.policytroubleshooter.iam.v3.ConditionContext"
    }
}

/// Defines additional types related to [ConditionContext].
pub mod condition_context {
    #[allow(unused_imports)]
    use super::*;

    /// Core attributes for a resource. A resource is an
    /// addressable (named) entity provided by the destination service. For
    /// example, a Compute Engine instance.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct Resource {
        /// The name of the service that this resource belongs to, such as
        /// `compute.googleapis.com`. The service name might not match the DNS
        /// hostname that actually serves the request.
        ///
        /// For a full list of resource service values, see
        /// <https://cloud.google.com/iam/help/conditions/resource-services>
        pub service: std::string::String,

        /// The stable identifier (name) of a resource on the `service`. A resource
        /// can be logically identified as `//{resource.service}/{resource.name}`.
        /// Unlike the resource URI, the resource name doesn't contain any protocol
        /// and version information.
        ///
        /// For a list of full resource name formats, see
        /// <https://cloud.google.com/iam/help/troubleshooter/full-resource-names>
        pub name: std::string::String,

        /// The type of the resource, in the format `{service}/{kind}`.
        ///
        /// For a full list of resource type values, see
        /// <https://cloud.google.com/iam/help/conditions/resource-types>
        pub r#type: std::string::String,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl Resource {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [service][crate::model::condition_context::Resource::service].
        pub fn set_service<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
            self.service = v.into();
            self
        }

        /// Sets the value of [name][crate::model::condition_context::Resource::name].
        pub fn set_name<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
            self.name = v.into();
            self
        }

        /// Sets the value of [r#type][crate::model::condition_context::Resource::type].
        pub fn set_type<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
            self.r#type = v.into();
            self
        }
    }

    impl wkt::message::Message for Resource {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.policytroubleshooter.iam.v3.ConditionContext.Resource"
        }
    }

    /// This message defines attributes for a node that handles a network request.
    /// The node can be either a service or an application that sends, forwards,
    /// or receives the request. Service peers should fill in
    /// `principal` and `labels` as appropriate.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct Peer {
        /// The IPv4 or IPv6 address of the peer.
        pub ip: std::string::String,

        /// The network port of the peer.
        pub port: i64,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl Peer {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [ip][crate::model::condition_context::Peer::ip].
        pub fn set_ip<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
            self.ip = v.into();
            self
        }

        /// Sets the value of [port][crate::model::condition_context::Peer::port].
        pub fn set_port<T: std::convert::Into<i64>>(mut self, v: T) -> Self {
            self.port = v.into();
            self
        }
    }

    impl wkt::message::Message for Peer {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.policytroubleshooter.iam.v3.ConditionContext.Peer"
        }
    }

    /// This message defines attributes for an HTTP request. If the actual
    /// request is not an HTTP request, the runtime system should try to map
    /// the actual request to an equivalent HTTP request.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct Request {
        /// Optional. The timestamp when the destination service receives the first
        /// byte of the request.
        pub receive_time: std::option::Option<wkt::Timestamp>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl Request {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [receive_time][crate::model::condition_context::Request::receive_time].
        pub fn set_receive_time<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<wkt::Timestamp>,
        {
            self.receive_time = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [receive_time][crate::model::condition_context::Request::receive_time].
        pub fn set_or_clear_receive_time<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<wkt::Timestamp>,
        {
            self.receive_time = v.map(|x| x.into());
            self
        }
    }

    impl wkt::message::Message for Request {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.policytroubleshooter.iam.v3.ConditionContext.Request"
        }
    }

    /// A tag that applies to a resource during policy evaluation. Tags can be
    /// either directly bound to a resource or inherited from its ancestor.
    /// `EffectiveTag` contains the `name` and `namespaced_name` of the tag value
    /// and tag key, with additional fields of `inherited` to indicate the
    /// inheritance status of the effective tag.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct EffectiveTag {
        /// Output only. Resource name for TagValue in the format `tagValues/456`.
        pub tag_value: std::string::String,

        /// Output only. The namespaced name of the TagValue. Can be in the form
        /// `{organization_id}/{tag_key_short_name}/{tag_value_short_name}` or
        /// `{project_id}/{tag_key_short_name}/{tag_value_short_name}` or
        /// `{project_number}/{tag_key_short_name}/{tag_value_short_name}`.
        pub namespaced_tag_value: std::string::String,

        /// Output only. The name of the TagKey, in the format `tagKeys/{id}`, such
        /// as `tagKeys/123`.
        pub tag_key: std::string::String,

        /// Output only. The namespaced name of the TagKey. Can be in the form
        /// `{organization_id}/{tag_key_short_name}` or
        /// `{project_id}/{tag_key_short_name}` or
        /// `{project_number}/{tag_key_short_name}`.
        pub namespaced_tag_key: std::string::String,

        /// The parent name of the tag key.
        /// Must be in the format `organizations/{organization_id}` or
        /// `projects/{project_number}`
        pub tag_key_parent_name: std::string::String,

        /// Output only. Indicates the inheritance status of a tag value
        /// attached to the given resource. If the tag value is inherited from one of
        /// the resource's ancestors, inherited will be true. If false, then the tag
        /// value is directly attached to the resource, inherited will be false.
        pub inherited: bool,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl EffectiveTag {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [tag_value][crate::model::condition_context::EffectiveTag::tag_value].
        pub fn set_tag_value<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
            self.tag_value = v.into();
            self
        }

        /// Sets the value of [namespaced_tag_value][crate::model::condition_context::EffectiveTag::namespaced_tag_value].
        pub fn set_namespaced_tag_value<T: std::convert::Into<std::string::String>>(
            mut self,
            v: T,
        ) -> Self {
            self.namespaced_tag_value = v.into();
            self
        }

        /// Sets the value of [tag_key][crate::model::condition_context::EffectiveTag::tag_key].
        pub fn set_tag_key<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
            self.tag_key = v.into();
            self
        }

        /// Sets the value of [namespaced_tag_key][crate::model::condition_context::EffectiveTag::namespaced_tag_key].
        pub fn set_namespaced_tag_key<T: std::convert::Into<std::string::String>>(
            mut self,
            v: T,
        ) -> Self {
            self.namespaced_tag_key = v.into();
            self
        }

        /// Sets the value of [tag_key_parent_name][crate::model::condition_context::EffectiveTag::tag_key_parent_name].
        pub fn set_tag_key_parent_name<T: std::convert::Into<std::string::String>>(
            mut self,
            v: T,
        ) -> Self {
            self.tag_key_parent_name = v.into();
            self
        }

        /// Sets the value of [inherited][crate::model::condition_context::EffectiveTag::inherited].
        pub fn set_inherited<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
            self.inherited = v.into();
            self
        }
    }

    impl wkt::message::Message for EffectiveTag {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.policytroubleshooter.iam.v3.ConditionContext.EffectiveTag"
        }
    }
}

/// Details about how the relevant IAM allow policies affect the final access
/// state.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct AllowPolicyExplanation {
    /// Indicates whether the principal has the specified permission for the
    /// specified resource, based on evaluating all applicable IAM allow policies.
    pub allow_access_state: crate::model::AllowAccessState,

    /// List of IAM allow policies that were evaluated to check the principal's
    /// permissions, with annotations to indicate how each policy contributed to
    /// the final result.
    ///
    /// The list of policies includes the policy for the resource itself, as well
    /// as allow policies that are inherited from higher levels of the resource
    /// hierarchy, including the organization, the folder, and the project.
    ///
    /// To learn more about the resource hierarchy, see
    /// <https://cloud.google.com/iam/help/resource-hierarchy>.
    pub explained_policies: std::vec::Vec<crate::model::ExplainedAllowPolicy>,

    /// The relevance of the allow policy type to the overall access state.
    pub relevance: crate::model::HeuristicRelevance,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl AllowPolicyExplanation {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [allow_access_state][crate::model::AllowPolicyExplanation::allow_access_state].
    pub fn set_allow_access_state<T: std::convert::Into<crate::model::AllowAccessState>>(
        mut self,
        v: T,
    ) -> Self {
        self.allow_access_state = v.into();
        self
    }

    /// Sets the value of [explained_policies][crate::model::AllowPolicyExplanation::explained_policies].
    pub fn set_explained_policies<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::ExplainedAllowPolicy>,
    {
        use std::iter::Iterator;
        self.explained_policies = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [relevance][crate::model::AllowPolicyExplanation::relevance].
    pub fn set_relevance<T: std::convert::Into<crate::model::HeuristicRelevance>>(
        mut self,
        v: T,
    ) -> Self {
        self.relevance = v.into();
        self
    }
}

impl wkt::message::Message for AllowPolicyExplanation {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.policytroubleshooter.iam.v3.AllowPolicyExplanation"
    }
}

/// Details about how a specific IAM allow policy contributed to the final access
/// state.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ExplainedAllowPolicy {
    /// Required. Indicates whether _this policy_ provides the specified permission
    /// to the specified principal for the specified resource.
    ///
    /// This field does _not_ indicate whether the principal actually has the
    /// permission for the resource. There might be another policy that overrides
    /// this policy. To determine whether the principal actually has the
    /// permission, use the `overall_access_state` field in the
    /// [TroubleshootIamPolicyResponse][google.cloud.policytroubleshooter.iam.v3.TroubleshootIamPolicyResponse].
    ///
    /// [google.cloud.policytroubleshooter.iam.v3.TroubleshootIamPolicyResponse]: crate::model::TroubleshootIamPolicyResponse
    pub allow_access_state: crate::model::AllowAccessState,

    /// The full resource name that identifies the resource. For example,
    /// `//compute.googleapis.com/projects/my-project/zones/us-central1-a/instances/my-instance`.
    ///
    /// If the sender of the request does not have access to the policy, this field
    /// is omitted.
    ///
    /// For examples of full resource names for Google Cloud services, see
    /// <https://cloud.google.com/iam/help/troubleshooter/full-resource-names>.
    pub full_resource_name: std::string::String,

    /// Details about how each role binding in the policy affects the principal's
    /// ability, or inability, to use the permission for the resource. The order of
    /// the role bindings matches the role binding order in the policy.
    ///
    /// If the sender of the request does not have access to the policy, this field
    /// is omitted.
    pub binding_explanations: std::vec::Vec<crate::model::AllowBindingExplanation>,

    /// The relevance of this policy to the overall access state in the
    /// [TroubleshootIamPolicyResponse][google.cloud.policytroubleshooter.iam.v3.TroubleshootIamPolicyResponse].
    ///
    /// If the sender of the request does not have access to the policy, this field
    /// is omitted.
    ///
    /// [google.cloud.policytroubleshooter.iam.v3.TroubleshootIamPolicyResponse]: crate::model::TroubleshootIamPolicyResponse
    pub relevance: crate::model::HeuristicRelevance,

    /// The IAM allow policy attached to the resource.
    ///
    /// If the sender of the request does not have access to the policy, this field
    /// is empty.
    pub policy: std::option::Option<iam_v1::model::Policy>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ExplainedAllowPolicy {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [allow_access_state][crate::model::ExplainedAllowPolicy::allow_access_state].
    pub fn set_allow_access_state<T: std::convert::Into<crate::model::AllowAccessState>>(
        mut self,
        v: T,
    ) -> Self {
        self.allow_access_state = v.into();
        self
    }

    /// Sets the value of [full_resource_name][crate::model::ExplainedAllowPolicy::full_resource_name].
    pub fn set_full_resource_name<T: std::convert::Into<std::string::String>>(
        mut self,
        v: T,
    ) -> Self {
        self.full_resource_name = v.into();
        self
    }

    /// Sets the value of [binding_explanations][crate::model::ExplainedAllowPolicy::binding_explanations].
    pub fn set_binding_explanations<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::AllowBindingExplanation>,
    {
        use std::iter::Iterator;
        self.binding_explanations = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [relevance][crate::model::ExplainedAllowPolicy::relevance].
    pub fn set_relevance<T: std::convert::Into<crate::model::HeuristicRelevance>>(
        mut self,
        v: T,
    ) -> Self {
        self.relevance = v.into();
        self
    }

    /// Sets the value of [policy][crate::model::ExplainedAllowPolicy::policy].
    pub fn set_policy<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<iam_v1::model::Policy>,
    {
        self.policy = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [policy][crate::model::ExplainedAllowPolicy::policy].
    pub fn set_or_clear_policy<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<iam_v1::model::Policy>,
    {
        self.policy = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for ExplainedAllowPolicy {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.policytroubleshooter.iam.v3.ExplainedAllowPolicy"
    }
}

/// Details about how a role binding in an allow policy affects a principal's
/// ability to use a permission.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct AllowBindingExplanation {
    /// Required. Indicates whether _this role binding_ gives the specified
    /// permission to the specified principal on the specified resource.
    ///
    /// This field does _not_ indicate whether the principal actually has the
    /// permission on the resource. There might be another role binding that
    /// overrides this role binding. To determine whether the principal actually
    /// has the permission, use the `overall_access_state` field in the
    /// [TroubleshootIamPolicyResponse][google.cloud.policytroubleshooter.iam.v3.TroubleshootIamPolicyResponse].
    ///
    /// [google.cloud.policytroubleshooter.iam.v3.TroubleshootIamPolicyResponse]: crate::model::TroubleshootIamPolicyResponse
    pub allow_access_state: crate::model::AllowAccessState,

    /// The role that this role binding grants. For example,
    /// `roles/compute.admin`.
    ///
    /// For a complete list of predefined IAM roles, as well as the permissions in
    /// each role, see <https://cloud.google.com/iam/help/roles/reference>.
    pub role: std::string::String,

    /// Indicates whether the role granted by this role binding contains the
    /// specified permission.
    pub role_permission: crate::model::RolePermissionInclusionState,

    /// The relevance of the permission's existence, or nonexistence, in the role
    /// to the overall determination for the entire policy.
    pub role_permission_relevance: crate::model::HeuristicRelevance,

    /// The combined result of all memberships. Indicates if the principal is
    /// included in any role binding, either directly or indirectly.
    pub combined_membership:
        std::option::Option<crate::model::allow_binding_explanation::AnnotatedAllowMembership>,

    /// Indicates whether each role binding includes the principal specified in the
    /// request, either directly or indirectly. Each key identifies a principal in
    /// the role binding, and each value indicates whether the principal in the
    /// role binding includes the principal in the request.
    ///
    /// For example, suppose that a role binding includes the following principals:
    ///
    /// * `user:alice@example.com`
    /// * `group:product-eng@example.com`
    ///
    /// You want to troubleshoot access for `user:bob@example.com`. This user is a
    /// member of the group `group:product-eng@example.com`.
    ///
    /// For the first principal in the role binding, the key is
    /// `user:alice@example.com`, and the `membership` field in the value is set to
    /// `NOT_INCLUDED`.
    ///
    /// For the second principal in the role binding, the key is
    /// `group:product-eng@example.com`, and the `membership` field in the value is
    /// set to `INCLUDED`.
    pub memberships: std::collections::HashMap<
        std::string::String,
        crate::model::allow_binding_explanation::AnnotatedAllowMembership,
    >,

    /// The relevance of this role binding to the overall determination for the
    /// entire policy.
    pub relevance: crate::model::HeuristicRelevance,

    /// A condition expression that specifies when the role binding grants access.
    ///
    /// To learn about IAM Conditions, see
    /// <https://cloud.google.com/iam/help/conditions/overview>.
    pub condition: std::option::Option<gtype::model::Expr>,

    /// Condition evaluation state for this role binding.
    pub condition_explanation: std::option::Option<crate::model::ConditionExplanation>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl AllowBindingExplanation {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [allow_access_state][crate::model::AllowBindingExplanation::allow_access_state].
    pub fn set_allow_access_state<T: std::convert::Into<crate::model::AllowAccessState>>(
        mut self,
        v: T,
    ) -> Self {
        self.allow_access_state = v.into();
        self
    }

    /// Sets the value of [role][crate::model::AllowBindingExplanation::role].
    pub fn set_role<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.role = v.into();
        self
    }

    /// Sets the value of [role_permission][crate::model::AllowBindingExplanation::role_permission].
    pub fn set_role_permission<
        T: std::convert::Into<crate::model::RolePermissionInclusionState>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.role_permission = v.into();
        self
    }

    /// Sets the value of [role_permission_relevance][crate::model::AllowBindingExplanation::role_permission_relevance].
    pub fn set_role_permission_relevance<
        T: std::convert::Into<crate::model::HeuristicRelevance>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.role_permission_relevance = v.into();
        self
    }

    /// Sets the value of [combined_membership][crate::model::AllowBindingExplanation::combined_membership].
    pub fn set_combined_membership<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::allow_binding_explanation::AnnotatedAllowMembership>,
    {
        self.combined_membership = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [combined_membership][crate::model::AllowBindingExplanation::combined_membership].
    pub fn set_or_clear_combined_membership<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::allow_binding_explanation::AnnotatedAllowMembership>,
    {
        self.combined_membership = v.map(|x| x.into());
        self
    }

    /// Sets the value of [memberships][crate::model::AllowBindingExplanation::memberships].
    pub fn set_memberships<T, K, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = (K, V)>,
        K: std::convert::Into<std::string::String>,
        V: std::convert::Into<crate::model::allow_binding_explanation::AnnotatedAllowMembership>,
    {
        use std::iter::Iterator;
        self.memberships = v.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
        self
    }

    /// Sets the value of [relevance][crate::model::AllowBindingExplanation::relevance].
    pub fn set_relevance<T: std::convert::Into<crate::model::HeuristicRelevance>>(
        mut self,
        v: T,
    ) -> Self {
        self.relevance = v.into();
        self
    }

    /// Sets the value of [condition][crate::model::AllowBindingExplanation::condition].
    pub fn set_condition<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<gtype::model::Expr>,
    {
        self.condition = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [condition][crate::model::AllowBindingExplanation::condition].
    pub fn set_or_clear_condition<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<gtype::model::Expr>,
    {
        self.condition = v.map(|x| x.into());
        self
    }

    /// Sets the value of [condition_explanation][crate::model::AllowBindingExplanation::condition_explanation].
    pub fn set_condition_explanation<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::ConditionExplanation>,
    {
        self.condition_explanation = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [condition_explanation][crate::model::AllowBindingExplanation::condition_explanation].
    pub fn set_or_clear_condition_explanation<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::ConditionExplanation>,
    {
        self.condition_explanation = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for AllowBindingExplanation {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.policytroubleshooter.iam.v3.AllowBindingExplanation"
    }
}

/// Defines additional types related to [AllowBindingExplanation].
pub mod allow_binding_explanation {
    #[allow(unused_imports)]
    use super::*;

    /// Details about whether the role binding includes the principal.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct AnnotatedAllowMembership {
        /// Indicates whether the role binding includes the principal.
        pub membership: crate::model::MembershipMatchingState,

        /// The relevance of the principal's status to the overall determination for
        /// the role binding.
        pub relevance: crate::model::HeuristicRelevance,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl AnnotatedAllowMembership {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [membership][crate::model::allow_binding_explanation::AnnotatedAllowMembership::membership].
        pub fn set_membership<T: std::convert::Into<crate::model::MembershipMatchingState>>(
            mut self,
            v: T,
        ) -> Self {
            self.membership = v.into();
            self
        }

        /// Sets the value of [relevance][crate::model::allow_binding_explanation::AnnotatedAllowMembership::relevance].
        pub fn set_relevance<T: std::convert::Into<crate::model::HeuristicRelevance>>(
            mut self,
            v: T,
        ) -> Self {
            self.relevance = v.into();
            self
        }
    }

    impl wkt::message::Message for AnnotatedAllowMembership {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.policytroubleshooter.iam.v3.AllowBindingExplanation.AnnotatedAllowMembership"
        }
    }
}

/// Details about how the relevant IAM deny policies affect the final access
/// state.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct DenyPolicyExplanation {
    /// Indicates whether the principal is denied the specified permission for
    /// the specified resource, based on evaluating all applicable IAM deny
    /// policies.
    pub deny_access_state: crate::model::DenyAccessState,

    /// List of resources with IAM deny policies that were evaluated to check the
    /// principal's denied permissions, with annotations to indicate how each
    /// policy contributed to the final result.
    ///
    /// The list of resources includes the policy for the resource itself, as well
    /// as policies that are inherited from higher levels of the resource
    /// hierarchy, including the organization, the folder, and the project. The
    /// order of the resources starts from the resource and climbs up the resource
    /// hierarchy.
    ///
    /// To learn more about the resource hierarchy, see
    /// <https://cloud.google.com/iam/help/resource-hierarchy>.
    pub explained_resources: std::vec::Vec<crate::model::ExplainedDenyResource>,

    /// The relevance of the deny policy result to the overall access state.
    pub relevance: crate::model::HeuristicRelevance,

    /// Indicates whether the permission to troubleshoot is supported in deny
    /// policies.
    pub permission_deniable: bool,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl DenyPolicyExplanation {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [deny_access_state][crate::model::DenyPolicyExplanation::deny_access_state].
    pub fn set_deny_access_state<T: std::convert::Into<crate::model::DenyAccessState>>(
        mut self,
        v: T,
    ) -> Self {
        self.deny_access_state = v.into();
        self
    }

    /// Sets the value of [explained_resources][crate::model::DenyPolicyExplanation::explained_resources].
    pub fn set_explained_resources<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::ExplainedDenyResource>,
    {
        use std::iter::Iterator;
        self.explained_resources = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [relevance][crate::model::DenyPolicyExplanation::relevance].
    pub fn set_relevance<T: std::convert::Into<crate::model::HeuristicRelevance>>(
        mut self,
        v: T,
    ) -> Self {
        self.relevance = v.into();
        self
    }

    /// Sets the value of [permission_deniable][crate::model::DenyPolicyExplanation::permission_deniable].
    pub fn set_permission_deniable<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
        self.permission_deniable = v.into();
        self
    }
}

impl wkt::message::Message for DenyPolicyExplanation {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.policytroubleshooter.iam.v3.DenyPolicyExplanation"
    }
}

/// Details about how a specific resource contributed to the deny policy
/// evaluation.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ExplainedDenyResource {
    /// Required. Indicates whether any policies attached to _this resource_ deny
    /// the specific permission to the specified principal for the specified
    /// resource.
    ///
    /// This field does _not_ indicate whether the principal actually has the
    /// permission for the resource. There might be another policy that overrides
    /// this policy. To determine whether the principal actually has the
    /// permission, use the `overall_access_state` field in the
    /// [TroubleshootIamPolicyResponse][google.cloud.policytroubleshooter.iam.v3.TroubleshootIamPolicyResponse].
    ///
    /// [google.cloud.policytroubleshooter.iam.v3.TroubleshootIamPolicyResponse]: crate::model::TroubleshootIamPolicyResponse
    pub deny_access_state: crate::model::DenyAccessState,

    /// The full resource name that identifies the resource. For example,
    /// `//compute.googleapis.com/projects/my-project/zones/us-central1-a/instances/my-instance`.
    ///
    /// If the sender of the request does not have access to the policy, this field
    /// is omitted.
    ///
    /// For examples of full resource names for Google Cloud services, see
    /// <https://cloud.google.com/iam/help/troubleshooter/full-resource-names>.
    pub full_resource_name: std::string::String,

    /// List of IAM deny policies that were evaluated to check the principal's
    /// denied permissions, with annotations to indicate how each policy
    /// contributed to the final result.
    pub explained_policies: std::vec::Vec<crate::model::ExplainedDenyPolicy>,

    /// The relevance of this policy to the overall access state in the
    /// [TroubleshootIamPolicyResponse][google.cloud.policytroubleshooter.iam.v3.TroubleshootIamPolicyResponse].
    ///
    /// If the sender of the request does not have access to the policy, this field
    /// is omitted.
    ///
    /// [google.cloud.policytroubleshooter.iam.v3.TroubleshootIamPolicyResponse]: crate::model::TroubleshootIamPolicyResponse
    pub relevance: crate::model::HeuristicRelevance,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ExplainedDenyResource {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [deny_access_state][crate::model::ExplainedDenyResource::deny_access_state].
    pub fn set_deny_access_state<T: std::convert::Into<crate::model::DenyAccessState>>(
        mut self,
        v: T,
    ) -> Self {
        self.deny_access_state = v.into();
        self
    }

    /// Sets the value of [full_resource_name][crate::model::ExplainedDenyResource::full_resource_name].
    pub fn set_full_resource_name<T: std::convert::Into<std::string::String>>(
        mut self,
        v: T,
    ) -> Self {
        self.full_resource_name = v.into();
        self
    }

    /// Sets the value of [explained_policies][crate::model::ExplainedDenyResource::explained_policies].
    pub fn set_explained_policies<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::ExplainedDenyPolicy>,
    {
        use std::iter::Iterator;
        self.explained_policies = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [relevance][crate::model::ExplainedDenyResource::relevance].
    pub fn set_relevance<T: std::convert::Into<crate::model::HeuristicRelevance>>(
        mut self,
        v: T,
    ) -> Self {
        self.relevance = v.into();
        self
    }
}

impl wkt::message::Message for ExplainedDenyResource {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.policytroubleshooter.iam.v3.ExplainedDenyResource"
    }
}

/// Details about how a specific IAM deny policy [Policy][google.iam.v2.Policy]
/// contributed to the access check.
///
/// [google.iam.v2.Policy]: iam_v2::model::Policy
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ExplainedDenyPolicy {
    /// Required. Indicates whether _this policy_ denies the specified permission
    /// to the specified principal for the specified resource.
    ///
    /// This field does _not_ indicate whether the principal actually has the
    /// permission for the resource. There might be another policy that overrides
    /// this policy. To determine whether the principal actually has the
    /// permission, use the `overall_access_state` field in the
    /// [TroubleshootIamPolicyResponse][google.cloud.policytroubleshooter.iam.v3.TroubleshootIamPolicyResponse].
    ///
    /// [google.cloud.policytroubleshooter.iam.v3.TroubleshootIamPolicyResponse]: crate::model::TroubleshootIamPolicyResponse
    pub deny_access_state: crate::model::DenyAccessState,

    /// The IAM deny policy attached to the resource.
    ///
    /// If the sender of the request does not have access to the policy, this field
    /// is omitted.
    pub policy: std::option::Option<iam_v2::model::Policy>,

    /// Details about how each rule in the policy affects the principal's inability
    /// to use the permission for the resource. The order of the deny rule matches
    /// the order of the rules in the deny policy.
    ///
    /// If the sender of the request does not have access to the policy, this field
    /// is omitted.
    pub rule_explanations: std::vec::Vec<crate::model::DenyRuleExplanation>,

    /// The relevance of this policy to the overall access state in the
    /// [TroubleshootIamPolicyResponse][google.cloud.policytroubleshooter.iam.v3.TroubleshootIamPolicyResponse].
    ///
    /// If the sender of the request does not have access to the policy, this field
    /// is omitted.
    ///
    /// [google.cloud.policytroubleshooter.iam.v3.TroubleshootIamPolicyResponse]: crate::model::TroubleshootIamPolicyResponse
    pub relevance: crate::model::HeuristicRelevance,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ExplainedDenyPolicy {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [deny_access_state][crate::model::ExplainedDenyPolicy::deny_access_state].
    pub fn set_deny_access_state<T: std::convert::Into<crate::model::DenyAccessState>>(
        mut self,
        v: T,
    ) -> Self {
        self.deny_access_state = v.into();
        self
    }

    /// Sets the value of [policy][crate::model::ExplainedDenyPolicy::policy].
    pub fn set_policy<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<iam_v2::model::Policy>,
    {
        self.policy = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [policy][crate::model::ExplainedDenyPolicy::policy].
    pub fn set_or_clear_policy<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<iam_v2::model::Policy>,
    {
        self.policy = v.map(|x| x.into());
        self
    }

    /// Sets the value of [rule_explanations][crate::model::ExplainedDenyPolicy::rule_explanations].
    pub fn set_rule_explanations<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::DenyRuleExplanation>,
    {
        use std::iter::Iterator;
        self.rule_explanations = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [relevance][crate::model::ExplainedDenyPolicy::relevance].
    pub fn set_relevance<T: std::convert::Into<crate::model::HeuristicRelevance>>(
        mut self,
        v: T,
    ) -> Self {
        self.relevance = v.into();
        self
    }
}

impl wkt::message::Message for ExplainedDenyPolicy {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.policytroubleshooter.iam.v3.ExplainedDenyPolicy"
    }
}

/// Details about how a deny rule in a deny policy affects a principal's ability
/// to use a permission.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct DenyRuleExplanation {
    /// Required. Indicates whether _this rule_ denies the specified permission to
    /// the specified principal for the specified resource.
    ///
    /// This field does _not_ indicate whether the principal is actually denied on
    /// the permission for the resource. There might be another rule that overrides
    /// this rule. To determine whether the principal actually has the permission,
    /// use the `overall_access_state` field in the
    /// [TroubleshootIamPolicyResponse][google.cloud.policytroubleshooter.iam.v3.TroubleshootIamPolicyResponse].
    ///
    /// [google.cloud.policytroubleshooter.iam.v3.TroubleshootIamPolicyResponse]: crate::model::TroubleshootIamPolicyResponse
    pub deny_access_state: crate::model::DenyAccessState,

    /// Indicates whether the permission in the request is listed as a denied
    /// permission in the deny rule.
    pub combined_denied_permission:
        std::option::Option<crate::model::deny_rule_explanation::AnnotatedPermissionMatching>,

    /// Lists all denied permissions in the deny rule and indicates whether each
    /// permission matches the permission in the request.
    ///
    /// Each key identifies a denied permission in the rule, and each value
    /// indicates whether the denied permission matches the permission in the
    /// request.
    pub denied_permissions: std::collections::HashMap<
        std::string::String,
        crate::model::deny_rule_explanation::AnnotatedPermissionMatching,
    >,

    /// Indicates whether the permission in the request is listed as an exception
    /// permission in the deny rule.
    pub combined_exception_permission:
        std::option::Option<crate::model::deny_rule_explanation::AnnotatedPermissionMatching>,

    /// Lists all exception permissions in the deny rule and indicates whether each
    /// permission matches the permission in the request.
    ///
    /// Each key identifies a exception permission in the rule, and each value
    /// indicates whether the exception permission matches the permission in the
    /// request.
    pub exception_permissions: std::collections::HashMap<
        std::string::String,
        crate::model::deny_rule_explanation::AnnotatedPermissionMatching,
    >,

    /// Indicates whether the principal is listed as a denied principal in the
    /// deny rule, either directly or through membership in a principal set.
    pub combined_denied_principal:
        std::option::Option<crate::model::deny_rule_explanation::AnnotatedDenyPrincipalMatching>,

    /// Lists all denied principals in the deny rule and indicates whether each
    /// principal matches the principal in the request, either directly or through
    /// membership in a principal set.
    ///
    /// Each key identifies a denied principal in the rule, and each value
    /// indicates whether the denied principal matches the principal in the
    /// request.
    pub denied_principals: std::collections::HashMap<
        std::string::String,
        crate::model::deny_rule_explanation::AnnotatedDenyPrincipalMatching,
    >,

    /// Indicates whether the principal is listed as an exception principal in the
    /// deny rule, either directly or through membership in a principal set.
    pub combined_exception_principal:
        std::option::Option<crate::model::deny_rule_explanation::AnnotatedDenyPrincipalMatching>,

    /// Lists all exception principals in the deny rule and indicates whether each
    /// principal matches the principal in the request, either directly or through
    /// membership in a principal set.
    ///
    /// Each key identifies a exception principal in the rule, and each value
    /// indicates whether the exception principal matches the principal in the
    /// request.
    pub exception_principals: std::collections::HashMap<
        std::string::String,
        crate::model::deny_rule_explanation::AnnotatedDenyPrincipalMatching,
    >,

    /// The relevance of this role binding to the overall determination for the
    /// entire policy.
    pub relevance: crate::model::HeuristicRelevance,

    /// A condition expression that specifies when the deny rule denies the
    /// principal access.
    ///
    /// To learn about IAM Conditions, see
    /// <https://cloud.google.com/iam/help/conditions/overview>.
    pub condition: std::option::Option<gtype::model::Expr>,

    /// Condition evaluation state for this role binding.
    pub condition_explanation: std::option::Option<crate::model::ConditionExplanation>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl DenyRuleExplanation {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [deny_access_state][crate::model::DenyRuleExplanation::deny_access_state].
    pub fn set_deny_access_state<T: std::convert::Into<crate::model::DenyAccessState>>(
        mut self,
        v: T,
    ) -> Self {
        self.deny_access_state = v.into();
        self
    }

    /// Sets the value of [combined_denied_permission][crate::model::DenyRuleExplanation::combined_denied_permission].
    pub fn set_combined_denied_permission<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::deny_rule_explanation::AnnotatedPermissionMatching>,
    {
        self.combined_denied_permission = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [combined_denied_permission][crate::model::DenyRuleExplanation::combined_denied_permission].
    pub fn set_or_clear_combined_denied_permission<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::deny_rule_explanation::AnnotatedPermissionMatching>,
    {
        self.combined_denied_permission = v.map(|x| x.into());
        self
    }

    /// Sets the value of [denied_permissions][crate::model::DenyRuleExplanation::denied_permissions].
    pub fn set_denied_permissions<T, K, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = (K, V)>,
        K: std::convert::Into<std::string::String>,
        V: std::convert::Into<crate::model::deny_rule_explanation::AnnotatedPermissionMatching>,
    {
        use std::iter::Iterator;
        self.denied_permissions = v.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
        self
    }

    /// Sets the value of [combined_exception_permission][crate::model::DenyRuleExplanation::combined_exception_permission].
    pub fn set_combined_exception_permission<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::deny_rule_explanation::AnnotatedPermissionMatching>,
    {
        self.combined_exception_permission = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [combined_exception_permission][crate::model::DenyRuleExplanation::combined_exception_permission].
    pub fn set_or_clear_combined_exception_permission<T>(
        mut self,
        v: std::option::Option<T>,
    ) -> Self
    where
        T: std::convert::Into<crate::model::deny_rule_explanation::AnnotatedPermissionMatching>,
    {
        self.combined_exception_permission = v.map(|x| x.into());
        self
    }

    /// Sets the value of [exception_permissions][crate::model::DenyRuleExplanation::exception_permissions].
    pub fn set_exception_permissions<T, K, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = (K, V)>,
        K: std::convert::Into<std::string::String>,
        V: std::convert::Into<crate::model::deny_rule_explanation::AnnotatedPermissionMatching>,
    {
        use std::iter::Iterator;
        self.exception_permissions = v.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
        self
    }

    /// Sets the value of [combined_denied_principal][crate::model::DenyRuleExplanation::combined_denied_principal].
    pub fn set_combined_denied_principal<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::deny_rule_explanation::AnnotatedDenyPrincipalMatching>,
    {
        self.combined_denied_principal = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [combined_denied_principal][crate::model::DenyRuleExplanation::combined_denied_principal].
    pub fn set_or_clear_combined_denied_principal<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::deny_rule_explanation::AnnotatedDenyPrincipalMatching>,
    {
        self.combined_denied_principal = v.map(|x| x.into());
        self
    }

    /// Sets the value of [denied_principals][crate::model::DenyRuleExplanation::denied_principals].
    pub fn set_denied_principals<T, K, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = (K, V)>,
        K: std::convert::Into<std::string::String>,
        V: std::convert::Into<crate::model::deny_rule_explanation::AnnotatedDenyPrincipalMatching>,
    {
        use std::iter::Iterator;
        self.denied_principals = v.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
        self
    }

    /// Sets the value of [combined_exception_principal][crate::model::DenyRuleExplanation::combined_exception_principal].
    pub fn set_combined_exception_principal<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::deny_rule_explanation::AnnotatedDenyPrincipalMatching>,
    {
        self.combined_exception_principal = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [combined_exception_principal][crate::model::DenyRuleExplanation::combined_exception_principal].
    pub fn set_or_clear_combined_exception_principal<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::deny_rule_explanation::AnnotatedDenyPrincipalMatching>,
    {
        self.combined_exception_principal = v.map(|x| x.into());
        self
    }

    /// Sets the value of [exception_principals][crate::model::DenyRuleExplanation::exception_principals].
    pub fn set_exception_principals<T, K, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = (K, V)>,
        K: std::convert::Into<std::string::String>,
        V: std::convert::Into<crate::model::deny_rule_explanation::AnnotatedDenyPrincipalMatching>,
    {
        use std::iter::Iterator;
        self.exception_principals = v.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
        self
    }

    /// Sets the value of [relevance][crate::model::DenyRuleExplanation::relevance].
    pub fn set_relevance<T: std::convert::Into<crate::model::HeuristicRelevance>>(
        mut self,
        v: T,
    ) -> Self {
        self.relevance = v.into();
        self
    }

    /// Sets the value of [condition][crate::model::DenyRuleExplanation::condition].
    pub fn set_condition<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<gtype::model::Expr>,
    {
        self.condition = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [condition][crate::model::DenyRuleExplanation::condition].
    pub fn set_or_clear_condition<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<gtype::model::Expr>,
    {
        self.condition = v.map(|x| x.into());
        self
    }

    /// Sets the value of [condition_explanation][crate::model::DenyRuleExplanation::condition_explanation].
    pub fn set_condition_explanation<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::ConditionExplanation>,
    {
        self.condition_explanation = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [condition_explanation][crate::model::DenyRuleExplanation::condition_explanation].
    pub fn set_or_clear_condition_explanation<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::ConditionExplanation>,
    {
        self.condition_explanation = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for DenyRuleExplanation {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.policytroubleshooter.iam.v3.DenyRuleExplanation"
    }
}

/// Defines additional types related to [DenyRuleExplanation].
pub mod deny_rule_explanation {
    #[allow(unused_imports)]
    use super::*;

    /// Details about whether the permission in the request is denied by the
    /// deny rule.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct AnnotatedPermissionMatching {
        /// Indicates whether the permission in the request is denied by the deny
        /// rule.
        pub permission_matching_state: crate::model::PermissionPatternMatchingState,

        /// The relevance of the permission status to the overall determination for
        /// the rule.
        pub relevance: crate::model::HeuristicRelevance,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl AnnotatedPermissionMatching {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [permission_matching_state][crate::model::deny_rule_explanation::AnnotatedPermissionMatching::permission_matching_state].
        pub fn set_permission_matching_state<
            T: std::convert::Into<crate::model::PermissionPatternMatchingState>,
        >(
            mut self,
            v: T,
        ) -> Self {
            self.permission_matching_state = v.into();
            self
        }

        /// Sets the value of [relevance][crate::model::deny_rule_explanation::AnnotatedPermissionMatching::relevance].
        pub fn set_relevance<T: std::convert::Into<crate::model::HeuristicRelevance>>(
            mut self,
            v: T,
        ) -> Self {
            self.relevance = v.into();
            self
        }
    }

    impl wkt::message::Message for AnnotatedPermissionMatching {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.policytroubleshooter.iam.v3.DenyRuleExplanation.AnnotatedPermissionMatching"
        }
    }

    /// Details about whether the principal in the request is listed as a denied
    /// principal in the deny rule, either directly or through membership in a
    /// principal set.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct AnnotatedDenyPrincipalMatching {
        /// Indicates whether the principal is listed as a denied principal in the
        /// deny rule, either directly or through membership in a principal set.
        pub membership: crate::model::MembershipMatchingState,

        /// The relevance of the principal's status to the overall determination for
        /// the role binding.
        pub relevance: crate::model::HeuristicRelevance,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl AnnotatedDenyPrincipalMatching {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [membership][crate::model::deny_rule_explanation::AnnotatedDenyPrincipalMatching::membership].
        pub fn set_membership<T: std::convert::Into<crate::model::MembershipMatchingState>>(
            mut self,
            v: T,
        ) -> Self {
            self.membership = v.into();
            self
        }

        /// Sets the value of [relevance][crate::model::deny_rule_explanation::AnnotatedDenyPrincipalMatching::relevance].
        pub fn set_relevance<T: std::convert::Into<crate::model::HeuristicRelevance>>(
            mut self,
            v: T,
        ) -> Self {
            self.relevance = v.into();
            self
        }
    }

    impl wkt::message::Message for AnnotatedDenyPrincipalMatching {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.policytroubleshooter.iam.v3.DenyRuleExplanation.AnnotatedDenyPrincipalMatching"
        }
    }
}

/// Explanation for how a condition affects a principal's access
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ConditionExplanation {
    /// Value of the condition.
    pub value: std::option::Option<wkt::Value>,

    /// Any errors that prevented complete evaluation of the condition expression.
    pub errors: std::vec::Vec<rpc::model::Status>,

    /// The value of each statement of the condition expression. The value can be
    /// `true`, `false`, or `null`. The value is `null` if the statement can't be
    /// evaluated.
    pub evaluation_states: std::vec::Vec<crate::model::condition_explanation::EvaluationState>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ConditionExplanation {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [value][crate::model::ConditionExplanation::value].
    pub fn set_value<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Value>,
    {
        self.value = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [value][crate::model::ConditionExplanation::value].
    pub fn set_or_clear_value<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Value>,
    {
        self.value = v.map(|x| x.into());
        self
    }

    /// Sets the value of [errors][crate::model::ConditionExplanation::errors].
    pub fn set_errors<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<rpc::model::Status>,
    {
        use std::iter::Iterator;
        self.errors = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [evaluation_states][crate::model::ConditionExplanation::evaluation_states].
    pub fn set_evaluation_states<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::condition_explanation::EvaluationState>,
    {
        use std::iter::Iterator;
        self.evaluation_states = v.into_iter().map(|i| i.into()).collect();
        self
    }
}

impl wkt::message::Message for ConditionExplanation {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.policytroubleshooter.iam.v3.ConditionExplanation"
    }
}

/// Defines additional types related to [ConditionExplanation].
pub mod condition_explanation {
    #[allow(unused_imports)]
    use super::*;

    /// Evaluated state of a condition expression.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct EvaluationState {
        /// Start position of an expression in the condition, by character.
        pub start: i32,

        /// End position of an expression in the condition, by character,
        /// end included, for example: the end position of the first part of
        /// `a==b || c==d` would be 4.
        pub end: i32,

        /// Value of this expression.
        pub value: std::option::Option<wkt::Value>,

        /// Any errors that prevented complete evaluation of the condition
        /// expression.
        pub errors: std::vec::Vec<rpc::model::Status>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl EvaluationState {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [start][crate::model::condition_explanation::EvaluationState::start].
        pub fn set_start<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
            self.start = v.into();
            self
        }

        /// Sets the value of [end][crate::model::condition_explanation::EvaluationState::end].
        pub fn set_end<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
            self.end = v.into();
            self
        }

        /// Sets the value of [value][crate::model::condition_explanation::EvaluationState::value].
        pub fn set_value<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<wkt::Value>,
        {
            self.value = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [value][crate::model::condition_explanation::EvaluationState::value].
        pub fn set_or_clear_value<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<wkt::Value>,
        {
            self.value = v.map(|x| x.into());
            self
        }

        /// Sets the value of [errors][crate::model::condition_explanation::EvaluationState::errors].
        pub fn set_errors<T, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = V>,
            V: std::convert::Into<rpc::model::Status>,
        {
            use std::iter::Iterator;
            self.errors = v.into_iter().map(|i| i.into()).collect();
            self
        }
    }

    impl wkt::message::Message for EvaluationState {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.policytroubleshooter.iam.v3.ConditionExplanation.EvaluationState"
        }
    }
}

/// Whether IAM allow policies gives the principal the permission.
///
/// # Working with unknown values
///
/// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
/// additional enum variants at any time. Adding new variants is not considered
/// a breaking change. Applications should write their code in anticipation of:
///
/// - New values appearing in future releases of the client library, **and**
/// - New values received dynamically, without application changes.
///
/// Please consult the [Working with enums] section in the user guide for some
/// guidelines.
///
/// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub enum AllowAccessState {
    /// Not specified.
    Unspecified,
    /// The allow policy gives the principal the permission.
    Granted,
    /// The allow policy doesn't give the principal the permission.
    NotGranted,
    /// The allow policy gives the principal the permission if a condition
    /// expression evaluate to `true`. However, the sender of the request didn't
    /// provide enough context for Policy Troubleshooter to evaluate the condition
    /// expression.
    UnknownConditional,
    /// The sender of the request doesn't have access to all of the allow policies
    /// that Policy Troubleshooter needs to evaluate the principal's access.
    UnknownInfo,
    /// If set, the enum was initialized with an unknown value.
    ///
    /// Applications can examine the value using [AllowAccessState::value] or
    /// [AllowAccessState::name].
    UnknownValue(allow_access_state::UnknownValue),
}

#[doc(hidden)]
pub mod allow_access_state {
    #[allow(unused_imports)]
    use super::*;
    #[derive(Clone, Debug, PartialEq)]
    pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
}

impl AllowAccessState {
    /// Gets the enum value.
    ///
    /// Returns `None` if the enum contains an unknown value deserialized from
    /// the string representation of enums.
    pub fn value(&self) -> std::option::Option<i32> {
        match self {
            Self::Unspecified => std::option::Option::Some(0),
            Self::Granted => std::option::Option::Some(1),
            Self::NotGranted => std::option::Option::Some(2),
            Self::UnknownConditional => std::option::Option::Some(3),
            Self::UnknownInfo => std::option::Option::Some(4),
            Self::UnknownValue(u) => u.0.value(),
        }
    }

    /// Gets the enum value as a string.
    ///
    /// Returns `None` if the enum contains an unknown value deserialized from
    /// the integer representation of enums.
    pub fn name(&self) -> std::option::Option<&str> {
        match self {
            Self::Unspecified => std::option::Option::Some("ALLOW_ACCESS_STATE_UNSPECIFIED"),
            Self::Granted => std::option::Option::Some("ALLOW_ACCESS_STATE_GRANTED"),
            Self::NotGranted => std::option::Option::Some("ALLOW_ACCESS_STATE_NOT_GRANTED"),
            Self::UnknownConditional => {
                std::option::Option::Some("ALLOW_ACCESS_STATE_UNKNOWN_CONDITIONAL")
            }
            Self::UnknownInfo => std::option::Option::Some("ALLOW_ACCESS_STATE_UNKNOWN_INFO"),
            Self::UnknownValue(u) => u.0.name(),
        }
    }
}

impl std::default::Default for AllowAccessState {
    fn default() -> Self {
        use std::convert::From;
        Self::from(0)
    }
}

impl std::fmt::Display for AllowAccessState {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
        wkt::internal::display_enum(f, self.name(), self.value())
    }
}

impl std::convert::From<i32> for AllowAccessState {
    fn from(value: i32) -> Self {
        match value {
            0 => Self::Unspecified,
            1 => Self::Granted,
            2 => Self::NotGranted,
            3 => Self::UnknownConditional,
            4 => Self::UnknownInfo,
            _ => Self::UnknownValue(allow_access_state::UnknownValue(
                wkt::internal::UnknownEnumValue::Integer(value),
            )),
        }
    }
}

impl std::convert::From<&str> for AllowAccessState {
    fn from(value: &str) -> Self {
        use std::string::ToString;
        match value {
            "ALLOW_ACCESS_STATE_UNSPECIFIED" => Self::Unspecified,
            "ALLOW_ACCESS_STATE_GRANTED" => Self::Granted,
            "ALLOW_ACCESS_STATE_NOT_GRANTED" => Self::NotGranted,
            "ALLOW_ACCESS_STATE_UNKNOWN_CONDITIONAL" => Self::UnknownConditional,
            "ALLOW_ACCESS_STATE_UNKNOWN_INFO" => Self::UnknownInfo,
            _ => Self::UnknownValue(allow_access_state::UnknownValue(
                wkt::internal::UnknownEnumValue::String(value.to_string()),
            )),
        }
    }
}

impl serde::ser::Serialize for AllowAccessState {
    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        match self {
            Self::Unspecified => serializer.serialize_i32(0),
            Self::Granted => serializer.serialize_i32(1),
            Self::NotGranted => serializer.serialize_i32(2),
            Self::UnknownConditional => serializer.serialize_i32(3),
            Self::UnknownInfo => serializer.serialize_i32(4),
            Self::UnknownValue(u) => u.0.serialize(serializer),
        }
    }
}

impl<'de> serde::de::Deserialize<'de> for AllowAccessState {
    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        deserializer.deserialize_any(wkt::internal::EnumVisitor::<AllowAccessState>::new(
            ".google.cloud.policytroubleshooter.iam.v3.AllowAccessState",
        ))
    }
}

/// Whether IAM deny policies deny the principal the permission.
///
/// # Working with unknown values
///
/// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
/// additional enum variants at any time. Adding new variants is not considered
/// a breaking change. Applications should write their code in anticipation of:
///
/// - New values appearing in future releases of the client library, **and**
/// - New values received dynamically, without application changes.
///
/// Please consult the [Working with enums] section in the user guide for some
/// guidelines.
///
/// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub enum DenyAccessState {
    /// Not specified.
    Unspecified,
    /// The deny policy denies the principal the permission.
    Denied,
    /// The deny policy doesn't deny the principal the permission.
    NotDenied,
    /// The deny policy denies the principal the permission if a condition
    /// expression evaluates to `true`. However, the sender of the request didn't
    /// provide enough context for Policy Troubleshooter to evaluate the condition
    /// expression.
    UnknownConditional,
    /// The sender of the request does not have access to all of the deny policies
    /// that Policy Troubleshooter needs to evaluate the principal's access.
    UnknownInfo,
    /// If set, the enum was initialized with an unknown value.
    ///
    /// Applications can examine the value using [DenyAccessState::value] or
    /// [DenyAccessState::name].
    UnknownValue(deny_access_state::UnknownValue),
}

#[doc(hidden)]
pub mod deny_access_state {
    #[allow(unused_imports)]
    use super::*;
    #[derive(Clone, Debug, PartialEq)]
    pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
}

impl DenyAccessState {
    /// Gets the enum value.
    ///
    /// Returns `None` if the enum contains an unknown value deserialized from
    /// the string representation of enums.
    pub fn value(&self) -> std::option::Option<i32> {
        match self {
            Self::Unspecified => std::option::Option::Some(0),
            Self::Denied => std::option::Option::Some(1),
            Self::NotDenied => std::option::Option::Some(2),
            Self::UnknownConditional => std::option::Option::Some(3),
            Self::UnknownInfo => std::option::Option::Some(4),
            Self::UnknownValue(u) => u.0.value(),
        }
    }

    /// Gets the enum value as a string.
    ///
    /// Returns `None` if the enum contains an unknown value deserialized from
    /// the integer representation of enums.
    pub fn name(&self) -> std::option::Option<&str> {
        match self {
            Self::Unspecified => std::option::Option::Some("DENY_ACCESS_STATE_UNSPECIFIED"),
            Self::Denied => std::option::Option::Some("DENY_ACCESS_STATE_DENIED"),
            Self::NotDenied => std::option::Option::Some("DENY_ACCESS_STATE_NOT_DENIED"),
            Self::UnknownConditional => {
                std::option::Option::Some("DENY_ACCESS_STATE_UNKNOWN_CONDITIONAL")
            }
            Self::UnknownInfo => std::option::Option::Some("DENY_ACCESS_STATE_UNKNOWN_INFO"),
            Self::UnknownValue(u) => u.0.name(),
        }
    }
}

impl std::default::Default for DenyAccessState {
    fn default() -> Self {
        use std::convert::From;
        Self::from(0)
    }
}

impl std::fmt::Display for DenyAccessState {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
        wkt::internal::display_enum(f, self.name(), self.value())
    }
}

impl std::convert::From<i32> for DenyAccessState {
    fn from(value: i32) -> Self {
        match value {
            0 => Self::Unspecified,
            1 => Self::Denied,
            2 => Self::NotDenied,
            3 => Self::UnknownConditional,
            4 => Self::UnknownInfo,
            _ => Self::UnknownValue(deny_access_state::UnknownValue(
                wkt::internal::UnknownEnumValue::Integer(value),
            )),
        }
    }
}

impl std::convert::From<&str> for DenyAccessState {
    fn from(value: &str) -> Self {
        use std::string::ToString;
        match value {
            "DENY_ACCESS_STATE_UNSPECIFIED" => Self::Unspecified,
            "DENY_ACCESS_STATE_DENIED" => Self::Denied,
            "DENY_ACCESS_STATE_NOT_DENIED" => Self::NotDenied,
            "DENY_ACCESS_STATE_UNKNOWN_CONDITIONAL" => Self::UnknownConditional,
            "DENY_ACCESS_STATE_UNKNOWN_INFO" => Self::UnknownInfo,
            _ => Self::UnknownValue(deny_access_state::UnknownValue(
                wkt::internal::UnknownEnumValue::String(value.to_string()),
            )),
        }
    }
}

impl serde::ser::Serialize for DenyAccessState {
    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        match self {
            Self::Unspecified => serializer.serialize_i32(0),
            Self::Denied => serializer.serialize_i32(1),
            Self::NotDenied => serializer.serialize_i32(2),
            Self::UnknownConditional => serializer.serialize_i32(3),
            Self::UnknownInfo => serializer.serialize_i32(4),
            Self::UnknownValue(u) => u.0.serialize(serializer),
        }
    }
}

impl<'de> serde::de::Deserialize<'de> for DenyAccessState {
    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        deserializer.deserialize_any(wkt::internal::EnumVisitor::<DenyAccessState>::new(
            ".google.cloud.policytroubleshooter.iam.v3.DenyAccessState",
        ))
    }
}

/// Whether a role includes a specific permission.
///
/// # Working with unknown values
///
/// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
/// additional enum variants at any time. Adding new variants is not considered
/// a breaking change. Applications should write their code in anticipation of:
///
/// - New values appearing in future releases of the client library, **and**
/// - New values received dynamically, without application changes.
///
/// Please consult the [Working with enums] section in the user guide for some
/// guidelines.
///
/// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub enum RolePermissionInclusionState {
    /// Not specified.
    Unspecified,
    /// The permission is included in the role.
    RolePermissionIncluded,
    /// The permission is not included in the role.
    RolePermissionNotIncluded,
    /// The sender of the request is not allowed to access the role definition.
    RolePermissionUnknownInfo,
    /// If set, the enum was initialized with an unknown value.
    ///
    /// Applications can examine the value using [RolePermissionInclusionState::value] or
    /// [RolePermissionInclusionState::name].
    UnknownValue(role_permission_inclusion_state::UnknownValue),
}

#[doc(hidden)]
pub mod role_permission_inclusion_state {
    #[allow(unused_imports)]
    use super::*;
    #[derive(Clone, Debug, PartialEq)]
    pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
}

impl RolePermissionInclusionState {
    /// Gets the enum value.
    ///
    /// Returns `None` if the enum contains an unknown value deserialized from
    /// the string representation of enums.
    pub fn value(&self) -> std::option::Option<i32> {
        match self {
            Self::Unspecified => std::option::Option::Some(0),
            Self::RolePermissionIncluded => std::option::Option::Some(1),
            Self::RolePermissionNotIncluded => std::option::Option::Some(2),
            Self::RolePermissionUnknownInfo => std::option::Option::Some(3),
            Self::UnknownValue(u) => u.0.value(),
        }
    }

    /// Gets the enum value as a string.
    ///
    /// Returns `None` if the enum contains an unknown value deserialized from
    /// the integer representation of enums.
    pub fn name(&self) -> std::option::Option<&str> {
        match self {
            Self::Unspecified => {
                std::option::Option::Some("ROLE_PERMISSION_INCLUSION_STATE_UNSPECIFIED")
            }
            Self::RolePermissionIncluded => std::option::Option::Some("ROLE_PERMISSION_INCLUDED"),
            Self::RolePermissionNotIncluded => {
                std::option::Option::Some("ROLE_PERMISSION_NOT_INCLUDED")
            }
            Self::RolePermissionUnknownInfo => {
                std::option::Option::Some("ROLE_PERMISSION_UNKNOWN_INFO")
            }
            Self::UnknownValue(u) => u.0.name(),
        }
    }
}

impl std::default::Default for RolePermissionInclusionState {
    fn default() -> Self {
        use std::convert::From;
        Self::from(0)
    }
}

impl std::fmt::Display for RolePermissionInclusionState {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
        wkt::internal::display_enum(f, self.name(), self.value())
    }
}

impl std::convert::From<i32> for RolePermissionInclusionState {
    fn from(value: i32) -> Self {
        match value {
            0 => Self::Unspecified,
            1 => Self::RolePermissionIncluded,
            2 => Self::RolePermissionNotIncluded,
            3 => Self::RolePermissionUnknownInfo,
            _ => Self::UnknownValue(role_permission_inclusion_state::UnknownValue(
                wkt::internal::UnknownEnumValue::Integer(value),
            )),
        }
    }
}

impl std::convert::From<&str> for RolePermissionInclusionState {
    fn from(value: &str) -> Self {
        use std::string::ToString;
        match value {
            "ROLE_PERMISSION_INCLUSION_STATE_UNSPECIFIED" => Self::Unspecified,
            "ROLE_PERMISSION_INCLUDED" => Self::RolePermissionIncluded,
            "ROLE_PERMISSION_NOT_INCLUDED" => Self::RolePermissionNotIncluded,
            "ROLE_PERMISSION_UNKNOWN_INFO" => Self::RolePermissionUnknownInfo,
            _ => Self::UnknownValue(role_permission_inclusion_state::UnknownValue(
                wkt::internal::UnknownEnumValue::String(value.to_string()),
            )),
        }
    }
}

impl serde::ser::Serialize for RolePermissionInclusionState {
    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        match self {
            Self::Unspecified => serializer.serialize_i32(0),
            Self::RolePermissionIncluded => serializer.serialize_i32(1),
            Self::RolePermissionNotIncluded => serializer.serialize_i32(2),
            Self::RolePermissionUnknownInfo => serializer.serialize_i32(3),
            Self::UnknownValue(u) => u.0.serialize(serializer),
        }
    }
}

impl<'de> serde::de::Deserialize<'de> for RolePermissionInclusionState {
    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        deserializer.deserialize_any(
            wkt::internal::EnumVisitor::<RolePermissionInclusionState>::new(
                ".google.cloud.policytroubleshooter.iam.v3.RolePermissionInclusionState",
            ),
        )
    }
}

/// Whether the permission in the request matches the permission in the policy.
///
/// # Working with unknown values
///
/// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
/// additional enum variants at any time. Adding new variants is not considered
/// a breaking change. Applications should write their code in anticipation of:
///
/// - New values appearing in future releases of the client library, **and**
/// - New values received dynamically, without application changes.
///
/// Please consult the [Working with enums] section in the user guide for some
/// guidelines.
///
/// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub enum PermissionPatternMatchingState {
    /// Not specified.
    Unspecified,
    /// The permission in the request matches the permission in the policy.
    PermissionPatternMatched,
    /// The permission in the request matches the permission in the policy.
    PermissionPatternNotMatched,
    /// If set, the enum was initialized with an unknown value.
    ///
    /// Applications can examine the value using [PermissionPatternMatchingState::value] or
    /// [PermissionPatternMatchingState::name].
    UnknownValue(permission_pattern_matching_state::UnknownValue),
}

#[doc(hidden)]
pub mod permission_pattern_matching_state {
    #[allow(unused_imports)]
    use super::*;
    #[derive(Clone, Debug, PartialEq)]
    pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
}

impl PermissionPatternMatchingState {
    /// Gets the enum value.
    ///
    /// Returns `None` if the enum contains an unknown value deserialized from
    /// the string representation of enums.
    pub fn value(&self) -> std::option::Option<i32> {
        match self {
            Self::Unspecified => std::option::Option::Some(0),
            Self::PermissionPatternMatched => std::option::Option::Some(1),
            Self::PermissionPatternNotMatched => std::option::Option::Some(2),
            Self::UnknownValue(u) => u.0.value(),
        }
    }

    /// Gets the enum value as a string.
    ///
    /// Returns `None` if the enum contains an unknown value deserialized from
    /// the integer representation of enums.
    pub fn name(&self) -> std::option::Option<&str> {
        match self {
            Self::Unspecified => {
                std::option::Option::Some("PERMISSION_PATTERN_MATCHING_STATE_UNSPECIFIED")
            }
            Self::PermissionPatternMatched => {
                std::option::Option::Some("PERMISSION_PATTERN_MATCHED")
            }
            Self::PermissionPatternNotMatched => {
                std::option::Option::Some("PERMISSION_PATTERN_NOT_MATCHED")
            }
            Self::UnknownValue(u) => u.0.name(),
        }
    }
}

impl std::default::Default for PermissionPatternMatchingState {
    fn default() -> Self {
        use std::convert::From;
        Self::from(0)
    }
}

impl std::fmt::Display for PermissionPatternMatchingState {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
        wkt::internal::display_enum(f, self.name(), self.value())
    }
}

impl std::convert::From<i32> for PermissionPatternMatchingState {
    fn from(value: i32) -> Self {
        match value {
            0 => Self::Unspecified,
            1 => Self::PermissionPatternMatched,
            2 => Self::PermissionPatternNotMatched,
            _ => Self::UnknownValue(permission_pattern_matching_state::UnknownValue(
                wkt::internal::UnknownEnumValue::Integer(value),
            )),
        }
    }
}

impl std::convert::From<&str> for PermissionPatternMatchingState {
    fn from(value: &str) -> Self {
        use std::string::ToString;
        match value {
            "PERMISSION_PATTERN_MATCHING_STATE_UNSPECIFIED" => Self::Unspecified,
            "PERMISSION_PATTERN_MATCHED" => Self::PermissionPatternMatched,
            "PERMISSION_PATTERN_NOT_MATCHED" => Self::PermissionPatternNotMatched,
            _ => Self::UnknownValue(permission_pattern_matching_state::UnknownValue(
                wkt::internal::UnknownEnumValue::String(value.to_string()),
            )),
        }
    }
}

impl serde::ser::Serialize for PermissionPatternMatchingState {
    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        match self {
            Self::Unspecified => serializer.serialize_i32(0),
            Self::PermissionPatternMatched => serializer.serialize_i32(1),
            Self::PermissionPatternNotMatched => serializer.serialize_i32(2),
            Self::UnknownValue(u) => u.0.serialize(serializer),
        }
    }
}

impl<'de> serde::de::Deserialize<'de> for PermissionPatternMatchingState {
    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        deserializer.deserialize_any(
            wkt::internal::EnumVisitor::<PermissionPatternMatchingState>::new(
                ".google.cloud.policytroubleshooter.iam.v3.PermissionPatternMatchingState",
            ),
        )
    }
}

/// Whether the principal in the request matches the principal in the policy.
///
/// # Working with unknown values
///
/// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
/// additional enum variants at any time. Adding new variants is not considered
/// a breaking change. Applications should write their code in anticipation of:
///
/// - New values appearing in future releases of the client library, **and**
/// - New values received dynamically, without application changes.
///
/// Please consult the [Working with enums] section in the user guide for some
/// guidelines.
///
/// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub enum MembershipMatchingState {
    /// Not specified.
    Unspecified,
    /// The principal in the request matches the principal in the policy. The
    /// principal can be included directly or indirectly:
    ///
    /// * A principal is included directly if that principal is listed in the
    ///   role binding.
    /// * A principal is included indirectly if that principal is in a Google
    ///   group, Google Workspace account, or Cloud Identity domain that is listed
    ///   in the policy.
    MembershipMatched,
    /// The principal in the request doesn't match the principal in the policy.
    MembershipNotMatched,
    /// The principal in the policy is a group or domain, and the sender of the
    /// request doesn't have permission to view whether the principal in the
    /// request is a member of the group or domain.
    MembershipUnknownInfo,
    /// The principal is an unsupported type.
    MembershipUnknownUnsupported,
    /// If set, the enum was initialized with an unknown value.
    ///
    /// Applications can examine the value using [MembershipMatchingState::value] or
    /// [MembershipMatchingState::name].
    UnknownValue(membership_matching_state::UnknownValue),
}

#[doc(hidden)]
pub mod membership_matching_state {
    #[allow(unused_imports)]
    use super::*;
    #[derive(Clone, Debug, PartialEq)]
    pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
}

impl MembershipMatchingState {
    /// Gets the enum value.
    ///
    /// Returns `None` if the enum contains an unknown value deserialized from
    /// the string representation of enums.
    pub fn value(&self) -> std::option::Option<i32> {
        match self {
            Self::Unspecified => std::option::Option::Some(0),
            Self::MembershipMatched => std::option::Option::Some(1),
            Self::MembershipNotMatched => std::option::Option::Some(2),
            Self::MembershipUnknownInfo => std::option::Option::Some(3),
            Self::MembershipUnknownUnsupported => std::option::Option::Some(4),
            Self::UnknownValue(u) => u.0.value(),
        }
    }

    /// Gets the enum value as a string.
    ///
    /// Returns `None` if the enum contains an unknown value deserialized from
    /// the integer representation of enums.
    pub fn name(&self) -> std::option::Option<&str> {
        match self {
            Self::Unspecified => std::option::Option::Some("MEMBERSHIP_MATCHING_STATE_UNSPECIFIED"),
            Self::MembershipMatched => std::option::Option::Some("MEMBERSHIP_MATCHED"),
            Self::MembershipNotMatched => std::option::Option::Some("MEMBERSHIP_NOT_MATCHED"),
            Self::MembershipUnknownInfo => std::option::Option::Some("MEMBERSHIP_UNKNOWN_INFO"),
            Self::MembershipUnknownUnsupported => {
                std::option::Option::Some("MEMBERSHIP_UNKNOWN_UNSUPPORTED")
            }
            Self::UnknownValue(u) => u.0.name(),
        }
    }
}

impl std::default::Default for MembershipMatchingState {
    fn default() -> Self {
        use std::convert::From;
        Self::from(0)
    }
}

impl std::fmt::Display for MembershipMatchingState {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
        wkt::internal::display_enum(f, self.name(), self.value())
    }
}

impl std::convert::From<i32> for MembershipMatchingState {
    fn from(value: i32) -> Self {
        match value {
            0 => Self::Unspecified,
            1 => Self::MembershipMatched,
            2 => Self::MembershipNotMatched,
            3 => Self::MembershipUnknownInfo,
            4 => Self::MembershipUnknownUnsupported,
            _ => Self::UnknownValue(membership_matching_state::UnknownValue(
                wkt::internal::UnknownEnumValue::Integer(value),
            )),
        }
    }
}

impl std::convert::From<&str> for MembershipMatchingState {
    fn from(value: &str) -> Self {
        use std::string::ToString;
        match value {
            "MEMBERSHIP_MATCHING_STATE_UNSPECIFIED" => Self::Unspecified,
            "MEMBERSHIP_MATCHED" => Self::MembershipMatched,
            "MEMBERSHIP_NOT_MATCHED" => Self::MembershipNotMatched,
            "MEMBERSHIP_UNKNOWN_INFO" => Self::MembershipUnknownInfo,
            "MEMBERSHIP_UNKNOWN_UNSUPPORTED" => Self::MembershipUnknownUnsupported,
            _ => Self::UnknownValue(membership_matching_state::UnknownValue(
                wkt::internal::UnknownEnumValue::String(value.to_string()),
            )),
        }
    }
}

impl serde::ser::Serialize for MembershipMatchingState {
    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        match self {
            Self::Unspecified => serializer.serialize_i32(0),
            Self::MembershipMatched => serializer.serialize_i32(1),
            Self::MembershipNotMatched => serializer.serialize_i32(2),
            Self::MembershipUnknownInfo => serializer.serialize_i32(3),
            Self::MembershipUnknownUnsupported => serializer.serialize_i32(4),
            Self::UnknownValue(u) => u.0.serialize(serializer),
        }
    }
}

impl<'de> serde::de::Deserialize<'de> for MembershipMatchingState {
    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        deserializer.deserialize_any(wkt::internal::EnumVisitor::<MembershipMatchingState>::new(
            ".google.cloud.policytroubleshooter.iam.v3.MembershipMatchingState",
        ))
    }
}

/// The extent to which a single data point contributes to an overall
/// determination.
///
/// # Working with unknown values
///
/// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
/// additional enum variants at any time. Adding new variants is not considered
/// a breaking change. Applications should write their code in anticipation of:
///
/// - New values appearing in future releases of the client library, **and**
/// - New values received dynamically, without application changes.
///
/// Please consult the [Working with enums] section in the user guide for some
/// guidelines.
///
/// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub enum HeuristicRelevance {
    /// Not specified.
    Unspecified,
    /// The data point has a limited effect on the result. Changing the data point
    /// is unlikely to affect the overall determination.
    Normal,
    /// The data point has a strong effect on the result. Changing the data point
    /// is likely to affect the overall determination.
    High,
    /// If set, the enum was initialized with an unknown value.
    ///
    /// Applications can examine the value using [HeuristicRelevance::value] or
    /// [HeuristicRelevance::name].
    UnknownValue(heuristic_relevance::UnknownValue),
}

#[doc(hidden)]
pub mod heuristic_relevance {
    #[allow(unused_imports)]
    use super::*;
    #[derive(Clone, Debug, PartialEq)]
    pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
}

impl HeuristicRelevance {
    /// Gets the enum value.
    ///
    /// Returns `None` if the enum contains an unknown value deserialized from
    /// the string representation of enums.
    pub fn value(&self) -> std::option::Option<i32> {
        match self {
            Self::Unspecified => std::option::Option::Some(0),
            Self::Normal => std::option::Option::Some(1),
            Self::High => std::option::Option::Some(2),
            Self::UnknownValue(u) => u.0.value(),
        }
    }

    /// Gets the enum value as a string.
    ///
    /// Returns `None` if the enum contains an unknown value deserialized from
    /// the integer representation of enums.
    pub fn name(&self) -> std::option::Option<&str> {
        match self {
            Self::Unspecified => std::option::Option::Some("HEURISTIC_RELEVANCE_UNSPECIFIED"),
            Self::Normal => std::option::Option::Some("HEURISTIC_RELEVANCE_NORMAL"),
            Self::High => std::option::Option::Some("HEURISTIC_RELEVANCE_HIGH"),
            Self::UnknownValue(u) => u.0.name(),
        }
    }
}

impl std::default::Default for HeuristicRelevance {
    fn default() -> Self {
        use std::convert::From;
        Self::from(0)
    }
}

impl std::fmt::Display for HeuristicRelevance {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
        wkt::internal::display_enum(f, self.name(), self.value())
    }
}

impl std::convert::From<i32> for HeuristicRelevance {
    fn from(value: i32) -> Self {
        match value {
            0 => Self::Unspecified,
            1 => Self::Normal,
            2 => Self::High,
            _ => Self::UnknownValue(heuristic_relevance::UnknownValue(
                wkt::internal::UnknownEnumValue::Integer(value),
            )),
        }
    }
}

impl std::convert::From<&str> for HeuristicRelevance {
    fn from(value: &str) -> Self {
        use std::string::ToString;
        match value {
            "HEURISTIC_RELEVANCE_UNSPECIFIED" => Self::Unspecified,
            "HEURISTIC_RELEVANCE_NORMAL" => Self::Normal,
            "HEURISTIC_RELEVANCE_HIGH" => Self::High,
            _ => Self::UnknownValue(heuristic_relevance::UnknownValue(
                wkt::internal::UnknownEnumValue::String(value.to_string()),
            )),
        }
    }
}

impl serde::ser::Serialize for HeuristicRelevance {
    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        match self {
            Self::Unspecified => serializer.serialize_i32(0),
            Self::Normal => serializer.serialize_i32(1),
            Self::High => serializer.serialize_i32(2),
            Self::UnknownValue(u) => u.0.serialize(serializer),
        }
    }
}

impl<'de> serde::de::Deserialize<'de> for HeuristicRelevance {
    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        deserializer.deserialize_any(wkt::internal::EnumVisitor::<HeuristicRelevance>::new(
            ".google.cloud.policytroubleshooter.iam.v3.HeuristicRelevance",
        ))
    }
}
